﻿using System;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace Gama.Extension
{
    public static partial class HtmlHelperExtensions
    {
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int totalItemCount, object routeValues)
        {
            return MvcHtmlString.Create(PageDefault(helper, currentPage, 5, 5, totalItemCount, routeValues).ToString());
        }
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int pageSize, int totalItemCount, object routeValues)
        {
            return MvcHtmlString.Create(PageDefault(helper, currentPage, pageSize, 5, totalItemCount, routeValues).ToString());
        }
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int pageSize, int groupSize, int totalItemCount, object routeValues)
        {
            return MvcHtmlString.Create(PageDefault(helper, currentPage, pageSize, groupSize, totalItemCount, routeValues).ToString());
        }
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int pageSize, int groupSize, int totalItemCount, bool showDetail, object routeValues)
        {
            var tagDefault = PageDefault(helper, currentPage, pageSize, groupSize, totalItemCount, routeValues);
            var tagDetail = BuildTabDetail(currentPage, pageSize, totalItemCount);
            tagDefault.InnerHtml += tagDetail.ToString();
            return MvcHtmlString.Create(tagDefault.ToString());
        }
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int pageSize, int groupSize, int totalItemCount, object routeValues, bool showTextBoxPage)
        {
            var tagDefault = PageDefault(helper, currentPage, pageSize, groupSize, totalItemCount, routeValues);
            var tagTextbox = BuildTabPageTextBox(currentPage, pageSize, totalItemCount);
            tagDefault.InnerHtml += tagTextbox.ToString();
            return MvcHtmlString.Create(tagDefault.ToString());
        }
        public static MvcHtmlString Pager(this HtmlHelper helper, int currentPage, int pageSize, int groupSize, int totalItemCount, bool showTextBoxPage, bool showDetail, object routeValues)
        {
            var tagDefault = PageDefault(helper, currentPage, pageSize, groupSize, totalItemCount, routeValues);
            if (showDetail)
            {
                var tagDetail = BuildTabDetail(currentPage, pageSize, totalItemCount);
                tagDefault.InnerHtml += tagDetail.ToString();
            }
            if (showTextBoxPage)
            {
                var tagTextbox = BuildTabPageTextBox(currentPage, pageSize, totalItemCount);
                tagDefault.InnerHtml += tagTextbox.ToString();
            }
            return MvcHtmlString.Create(tagDefault.ToString());
        }
        private static TagBuilder BuildTabDetail(int currentPage, int pageSize, int totalItemCount)
        {
            //Add item from ... to ... of ...
            var tagDetail = new TagBuilder("div");
            tagDetail.AddCssClass("page-status-text");
            var data = string.Format("Hiển thị {0} - {1} của {2}", (currentPage - 1) * pageSize + 1, currentPage * pageSize, totalItemCount);
            tagDetail.SetInnerText(data);
            return tagDetail;
        }
        private static TagBuilder BuildTabPageTextBox(int currentPage, int pageSize, int totalItemCount)
        {
            //Add textbox page
            var pageCount = (int)Math.Ceiling(totalItemCount / (double)pageSize);
            var tagTextbox = new TagBuilder("div");
            tagTextbox.AddCssClass("page-div-textbox");
            var tagTEXTBOX = new TagBuilder("input");
            tagTEXTBOX.AddCssClass("page-textbox");
            tagTEXTBOX.MergeAttribute("type", "text");
            tagTEXTBOX.MergeAttribute("value", currentPage.ToString());
            tagTextbox.InnerHtml += string.Format("Trang {0} của {1}", tagTEXTBOX.ToString(), pageCount);
            return tagTextbox;
        }

        private static TagBuilder PageDefault(HtmlHelper helper, int currentPage, int pageSize, int groupSize, int totalItemCount, object routeValues)
        {
            // how many pages to display in each page group const             
            var pageCount = (int)Math.Ceiling(totalItemCount / (double)pageSize);
            currentPage = currentPage > pageCount ? pageCount : currentPage;
            currentPage = currentPage < 1 ? 1 : currentPage;
            // cleanup any out bounds page number passed   
            currentPage = Math.Max(currentPage, 1);
            currentPage = Math.Min(currentPage, pageCount);
            var urlHelper = new UrlHelper(helper.ViewContext.RequestContext, helper.RouteCollection);
            var pageContainer = new TagBuilder("div");
            pageContainer.AddCssClass("page-container");
            var container = new TagBuilder("ul");
            container.AddCssClass("pager");
            var actionName = helper.ViewContext.RouteData.GetRequiredString("Action");
            // calculate the last page group number starting from the current page     
            // until we hit the next whole divisible number    
            var lastGroupNumber = currentPage;
            while ((lastGroupNumber % groupSize != 0)) lastGroupNumber++;
            // correct if we went over the number of pages     
            var groupEnd = Math.Min(lastGroupNumber, pageCount);
            // work out the first page group number, we use the lastGroupNumber instead of     
            // groupEnd so that we don't include numbers from the previous group if we went    
            // over the page count     
            var groupStart = lastGroupNumber - (groupSize - 1);
            // build tabLI            
            var tagLI = new TagBuilder("li");

            // if we are past the first page   
            if (currentPage > 1)
            {
                var buttonPre_First = new TagBuilder("ul");
                buttonPre_First.AddCssClass("page-pre-first");
                // First page
                var first = new TagBuilder("a");
                //previous.SetInnerText("<");
                first.AddCssClass("page-link first");
                //var routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", 1);
                //first.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                first.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, 1));

                var tagSpan = new TagBuilder("span");
                tagSpan.AddCssClass("page-icon page-first");
                tagSpan.SetInnerText("First");

                first.InnerHtml = tagSpan.ToString();
                tagLI.InnerHtml = first.ToString();
                buttonPre_First.InnerHtml += tagLI.ToString();

                // previous link
                var previous = new TagBuilder("a");
                //previous.SetInnerText("<");
                previous.AddCssClass("page-link previous");
                //routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", currentPage - 1);
                //previous.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                previous.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, currentPage-1));
                tagSpan = new TagBuilder("span");
                tagSpan.AddCssClass("page-icon page-previous");
                tagSpan.SetInnerText("Previous");

                previous.InnerHtml = tagSpan.ToString();
                tagLI.InnerHtml = previous.ToString();
                buttonPre_First.InnerHtml += tagLI.ToString();

                //Add Firs-Previous to container
                pageContainer.InnerHtml += buttonPre_First.ToString();
            }
            // if we have past the first page group    
            if (currentPage > groupSize)
            {
                var previousDots = new TagBuilder("a");
                previousDots.SetInnerText("...");
                previousDots.AddCssClass("page-link previous-dots");
                //var routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", groupStart - groupSize);
                //previousDots.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                previousDots.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, groupStart-groupSize));
                tagLI.InnerHtml = previousDots.ToString();
                container.InnerHtml += tagLI.ToString();
            }
            for (var i = groupStart; i <= groupEnd; i++)
            {
                var pageNumber = new TagBuilder("a");
                pageNumber.AddCssClass(((i == currentPage)) ? "page-link selected-page" : "page-link");
                pageNumber.SetInnerText((i).ToString());
               // var routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", i);
                pageNumber.MergeAttribute("href", string.Format("{0}?page={1}",routeValues, i));
                if(i == currentPage)
                    pageNumber.MergeAttribute("onclick", "return false");
                tagLI.InnerHtml = pageNumber.ToString();
                container.InnerHtml += tagLI.ToString();
            }
            // if there are still pages past the end of this page group    
            if (pageCount > groupEnd)
            {
                var nextDots = new TagBuilder("a");
                nextDots.SetInnerText("...");
                nextDots.AddCssClass("page-link next-dots");
                //var routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", groupEnd + 1);
                //nextDots.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                nextDots.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, groupEnd+1));
                tagLI.InnerHtml = nextDots.ToString();
                container.InnerHtml += tagLI.ToString();
            }
            //Add page link to contain
            pageContainer.InnerHtml += container.ToString();
            // if we still have pages left to show     
            if (currentPage < pageCount)
            {
                var buttonNext_Last = new TagBuilder("ul");
                buttonNext_Last.AddCssClass("page-next-last");
                //Nex page
                var next = new TagBuilder("a");
                //next.SetInnerText(">");
                next.AddCssClass("page-link");
                //var routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", currentPage + 1);
                //next.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                next.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, currentPage + 1));

                var tagSpan = new TagBuilder("span");
                tagSpan.AddCssClass("page-icon page-next");
                tagSpan.SetInnerText("Next");

                next.InnerHtml = tagSpan.ToString();
                tagLI.InnerHtml = next.ToString();
                buttonNext_Last.InnerHtml += tagLI.ToString();

                // Last page
                var last = new TagBuilder("a");
                //next.SetInnerText(">");
                last.AddCssClass("page-link");
                //routingValues = new RouteValueDictionary(routeValues);
                //routingValues.Add("page", pageCount);
                //last.MergeAttribute("href", urlHelper.Action(actionName, routingValues));
                last.MergeAttribute("href", string.Format("{0}?page={1}", routeValues, pageCount));

                tagSpan = new TagBuilder("span");
                tagSpan.AddCssClass("page-icon page-last");
                tagSpan.SetInnerText("Last");

                last.InnerHtml = tagSpan.ToString();
                tagLI.InnerHtml = last.ToString();
                buttonNext_Last.InnerHtml += tagLI.ToString();

                //Add Last-Next to container
                pageContainer.InnerHtml += buttonNext_Last.ToString();
            }

            return pageContainer;
        }        
    }
}